package com.puzzlebazar.client.heyawake;

import com.puzzlebazar.client.puzzle.model.Move;
import com.puzzlebazar.client.squaregrid.control.ControlView;
import com.puzzlebazar.client.squaregrid.view.GridDisplay;
import com.puzzlebazar.client.squaregrid.view.SGViewImpl;
import com.puzzlebazar.client.squaregrid.view.DrawableLayer;
import com.puzzlebazar.client.util.Observable;
import com.puzzlebazar.client.util.Vec2i;

public final class HeyawakeView extends SGViewImpl {
	
	private final GridDisplay displayDecorator = new GridDisplay();
	private final DrawableLayer cellLayer = new DrawableLayer();
	private final DrawableLayer gridLayer = new DrawableLayer();
	private final DrawableLayer stringLayer = new DrawableLayer();
	private final DrawableLayer highlightLayer = new DrawableLayer();
	private final ControlView controlDecorator = new ControlView();

	private final DrawMoveVisitor drawVisitor;
	
	/**
	 * Creates a new standard heyawake view
	 * 
	 * @param model  Heyawake model to view
	 * @param pixelSize Horizontal/Vertical size, in pixels
	 * @param bleed Amount of bleed around grid, in pixels
	 * @throws Exception
	 */
	public HeyawakeView( HeyawakeModel model, Vec2i pixelSize, int bleed ) throws Exception {
		super( model, pixelSize, bleed );

		add( displayDecorator );		
		add( cellLayer );		
		add( gridLayer );		
		add( stringLayer );		
		add( highlightLayer );		
		add( controlDecorator );		
		
		drawVisitor = new DrawMoveVisitor( cellLayer, gridLayer, stringLayer );

		model.addObserver( this );
	}

	/**
	 * @return The decorator for highlighting cells
	 */
	public DrawableLayer getHighlightLayer() {
		return highlightLayer;
	}	

	/**
	 * @return The control decorator
	 */
	public ControlView getControlDecorator() {
		return controlDecorator;
	}


	@Override
	public void update(Observable observable, Object arg) {
		super.update(observable,arg);
		
		assert observable instanceof HeyawakeModel;
		HeyawakeModel model = (HeyawakeModel)observable;
		
		try {
			Move move;

			if( arg != null ) {
				assert arg instanceof Move;
				move = (Move)arg;
			}
			else {
				cellLayer.clear();
				gridLayer.clear();
				stringLayer.clear();
				move = model.getMoveList();
			}

			move.accept( drawVisitor );
		} catch (Exception exception) {
			exception.printStackTrace();
		}
	}

}
